#ifndef _KDATA_H_
#define _KDATA_H_
#include "FacilityBaseLib.h"
//#include "array_container.h"

#include "DataTypes.h"

inline bool operator == (const kdata_t& pTemp1, const kdata_t& pTemp2)
{
	return strcmp(pTemp1.szCode, pTemp2.szCode) == 0
		&& pTemp1.TradingTime == pTemp2.TradingTime;
}

inline bool operator < (const kdata_t& pTemp1, const kdata_t& pTemp2)
{
	return strcmp(pTemp1.szCode, pTemp2.szCode) == 0
		&& pTemp1.TradingTime < pTemp2.TradingTime;
}
//K线数据数组类
//template class FACILITY_API array_container<kdata_t>;
class ReportContainer;
class FACILITY_API KdataContainer:public std::vector<kdata_t>
{
public:
	//K线数据类型;
	enum Formats{
		formatNone=0x00,
		formatMin=0x01,
		formatOriginal=0x01,
		formatXDRup=0x02,
		formatXDRdown=0x03,
		formatMax=0x03
	};
	enum MaindataTypes{
		mdtypeNone=0x00,
		mdtypeMin=0x01,
		mdtypeHigh=0x01,
		mdtypeClose=0x02,
		mdtypeOpen=0x03,
		mdtypeAverage=0x04,
		mdtypeLow=0x05,
		mdtypeVolume=0x06,
		mdtypeTrunover=0x07,
		mdtypeOpenInterest=0x08,
		mdtypeMax=0x07
	};
    virtual ~KdataContainer();
	KdataContainer();
	KdataContainer(int ktype,int maindatatype=mdtypeClose);
	KdataContainer( const KdataContainer & src );
	KdataContainer& operator=(const KdataContainer& src);
	static bool IsDayOrMin(int nKType);
public:
	//数组操作函数;
	int GetUpperBound() const;
	//void SetAt(int nIndex,KDATA newElement);

	int  InsertKDataSort(const KDATA& newElement );
	//目前还不确定要如何管理时间;
	//与K线相关的函数
	//得到kdata_container的nIndex日的主数据，根据主数据类型不同，返回值可以是开盘价，收盘价或平均价;
	double MaindataAt(size_t nIndex) const;
	//得到nIndex日的具体时间,这个函数用的似乎少;
	bool DateAt(size_t nIndex,int &nYear,int &nMonth,int &nDay,int &nHour,int &nMinute) const;
	//获得最近日期;
	bool LatestDate(int &nYear,int &nMonth,int &nDay,int &nHour,int &nMinute) const;
	//通过索引获得日期;
	
	DWORD GetDate(size_t nIndex);
	DWORD GetDateDay(int nIndex);

	//通过日期获得索引;
	int GetIndexByDate(DWORD date );
	int GetAboutIndexByDate(DWORD date);
	
	bool IsNewValue(size_t nIndex,bool bTopOrBottom,size_t nDays);
	bool GetMinMaxInfo(size_t nStart,size_t nEnd,double* pfMin,double* pfMax);
	//根据TICK更新数据;
	bool update(const Tick* pTick);
public:
	void SetKType(int ktype);
	void AutoSetKType();
	int GetKType();
	int GetCurFormat();
	void ChangeCurFormat(int format,DWORD dateAutoDRBegin,double dAutoDRLimit);
	void SetMaindataType(int type);
	int GetMaindataType();
	void Clear();
	int CompareLatestDate(KdataContainer& kd);
	static int Min5ToMin15(KdataContainer& kdm5,KdataContainer& kdm15);
	static int Min5ToMin30(KdataContainer& kdm5,KdataContainer& kdm30);
	static int Min5ToMin60(KdataContainer& kdm5,KdataContainer& kdm60);
	//将1分钟线转换成日线;
	static int Min1ToDay(KdataContainer& kdm15, KdataContainer& kdday);
	static int DayToMonth(KdataContainer& kdday,KdataContainer& kdmonth);
	static int DayToWeek(KdataContainer& kdday,KdataContainer& kdweek);
	DWORD	ToDayDate( DWORD date );

	int		MergeKData( KdataContainer * pother );
	int		FullFillKData( KdataContainer & kdataMain, bool bFillToEnd );

	bool	IsAdjacentDays( size_t nIndex, size_t nDays );
	bool	GetDiff( double * pValue, DWORD dateCur, int nDays );
	bool	GetDiffPercent( double * pValue, DWORD dateCur, int nDays );
	bool	GetScope( double * pValue, DWORD dateCur, int nDays );
	bool	GetVolumeSum( double * pValue, DWORD dateCur, int nDays );
	bool	GetRatioVolume( double * pValue, DWORD dateCur, int nDays );
	bool	GetRS( double * pValue, DWORD dateCur, int nDays );
	bool	GetMA(double * pValue, size_t nIndex, size_t nDays);
	static int ConvertKData( KdataContainer &kdSrc, KdataContainer &kdDest, int multiple );
	//将K线转换成Tick线;
	int		ToReport(ReportContainer & kdata);
protected:
	//void	CopyData( const kdata_container &src );
	void	LoadDataOriginal( );
	void	StoreDataOriginal( );
	void	ConvertXDR( bool bUP, DWORD dateAutoDRBegin, double dAutoDRLimit );
	
	//static	float	GetRatio( float fLastClose, DRDATA & dr );
protected:
	int		m_nKType;
	int		m_nCurFormat;
	int		m_nCurMaindataType;
	struct kdata_t * m_pDataOriginal;
	int m_nSizeOriginal;     // # of elements (upperBound - 1)
	int m_nMaxSizeOriginal;  // max allocated
	boost::shared_ptr<Tick> m_LastTickPtr;
};

#endif
